package com.java.example.network

import android.annotation.SuppressLint
import android.util.Base64
import android.util.Log
import com.google.gson.Gson
import com.google.gson.JsonIOException
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import okhttp3.ResponseBody
import retrofit2.Converter
import retrofit2.http.POST
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.security.KeyFactory
import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

/**
 * @author chenll
 * @date 2024/2/22
 * Des：
 */
internal class CustomResponseBodyConverter<T>(private val gson: Gson, private val adapter: TypeAdapter<T>, private val annotations: Array<Annotation>?) : Converter<ResponseBody, T> {
    @Throws(IOException::class)
    override fun convert(value: ResponseBody): T? {
        val jsonReader = gson.newJsonReader(value.charStream())
        var flag = true
        if (null != annotations) {
            for (item in annotations) {
                if (item is POST) {
                    if (item.value.contains("fileUpload/upload/uploadFile")) {
                        flag = false
                    }
                    break
                }
            }
        }
        // 解密
        if (flag) {
            val decryption = decryption(jsonReader)
            if (null != decryption) {
                value.close()
                return decryption
            }
        }

        //
        return try {
            val result = adapter.read(jsonReader)
            if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                throw JsonIOException("JSON document was not fully consumed.")
            }
            result
        } catch (e: Exception) {
            e.printStackTrace()
            null
        } finally {
            value.close()
        }
    }

    @SuppressLint("GetInstance")
    private fun decryption(jsonReader: JsonReader): T? {
        return try {
            val encryptBody = gson.fromJson<EncryptBody>(jsonReader, EncryptBody::class.java)
            val encrypted = encryptBody.encrypted
            val keySpec = PKCS8EncodedKeySpec(
                Base64.decode(CustomConvertFactory.CLIENT_PRIVATE_KEY, Base64.DEFAULT)
            )
            val keyFactory = KeyFactory.getInstance("RSA")
            val privateKey = keyFactory.generatePrivate(keySpec)
            val rsa = Cipher.getInstance("RSA/None/PKCS1Padding")
            rsa.init(Cipher.DECRYPT_MODE, privateKey)
            val aes_key = String(rsa.doFinal(Base64.decode(encrypted, Base64.DEFAULT)), StandardCharsets.UTF_8)
            //
            val requestData = encryptBody.requestData
            val aes = Cipher.getInstance("AES/ECB/PKCS5PADDING")
            aes.init(Cipher.DECRYPT_MODE, generateAESKey(aes_key))
            val data = String(aes.doFinal(Base64.decode(requestData, Base64.DEFAULT)), StandardCharsets.UTF_8)
            Log.d("解密结果","：$data")
            adapter.fromJson(data)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    private fun generateAESKey(key: String): SecretKeySpec {
        return SecretKeySpec(key.toByteArray(StandardCharsets.UTF_8), "AES/ECB/PKCS5PADDING")
    }
}
